package com.jade.modules.config.impl;

import java.util.*;
import javax.ejb.TransactionAttribute;
import javax.inject.Inject;
import javax.inject.Named;

import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.util.PagingList;
import com.jade.framework.base.util.Parameters;
import com.jade.framework.base.util.SimpleParameters;
import com.jade.modules.config.*;
import org.springframework.transaction.annotation.Transactional;

/**
 * 配置项管理实现。
 *
 * @author sky
 * @version 1.0 14-11-24 上午8:46
 */
@Named ("module_configManager")
public class ConfigManagerImpl
        implements ConfigManager
{
    protected ConfigDao configDao;

    @Inject
    public void setConfigDao(@Named ("module_configDao") ConfigDao configDao)
    {
        this.configDao = configDao;
    }

    public Parameters getConfig(String ownerType, String ownerId, String group)
    {
        List<ConfigEntity> entities = listEntity(ownerType, ownerId, group);
        Parameters params = new SimpleParameters();
        for (ConfigEntity entity : entities) {
            params.setString(entity.getKey(), entity.getValue());
        }
        return params;
    }

    public List<ConfigEntity> listEntity(String ownerType, String ownerId, String group)
    {
        return configDao.listEntity(ownerType, ownerId, group);
    }

    public PagingList<ConfigEntity> queryEntity(String ownerType, String ownerId, Criteria criteria)
    {
        return configDao.queryEntity(ownerType, ownerId, criteria);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void addEntity(ConfigEntity entity)
            throws ConfigException
    {
        if (getEntity(entity.getOwnerType(), entity.getOwnerId(), entity.getGroup(), entity.getKey()) != null) {
            throw new ConfigException("err.module.config.duplicated_key", "key existed", null, entity.getKey());
        }
        entity.setUpdateTime(new Date());
        configDao.addEntity(entity);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void updateEntity(ConfigEntity entity)
            throws ConfigException
    {
        entity.setUpdateTime(new Date());
        configDao.updateEntity(entity);
    }

    public ConfigEntity getEntity(String ownerType, String ownerId, String group, String key)
    {
        return configDao.getEntity(ownerType, ownerId, group, key);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void setEntity(String ownerType, String ownerId, String group, List<ConfigEntity> entities)
            throws ConfigException
    {
        List<ConfigEntity> olds = listEntity(ownerType, ownerId, group);
        List<ConfigEntity> added = new ArrayList<ConfigEntity>();
        List<ConfigEntity> updated = new ArrayList<ConfigEntity>();
        List<ConfigEntity> removed = new ArrayList<ConfigEntity>();
        Map<String, ConfigEntity> map = new HashMap<String, ConfigEntity>(olds.size());
        for (ConfigEntity entity : olds) {
            map.put(entity.getKey(), entity);
        }
        Date now = new Date();
        for (ConfigEntity entity : entities) {
            entity.setOwnerType(ownerType);
            entity.setOwnerId(ownerId);
            entity.setGroup(group);
            entity.setUpdateTime(now);
            ConfigEntity old = map.get(entity.getKey());
            if (old == null) {
                added.add(entity);
            }
            else {
                entity.setId(old.getId());
                updated.add(entity);
            }
        }
        map.clear();
        for (ConfigEntity entity : entities) {
            map.put(entity.getKey(), entity);
        }
        for (ConfigEntity entity : olds) {
            if (map.get(entity.getKey()) == null) {
                removed.add(entity);
            }
        }

        for (ConfigEntity entity : added) {
            configDao.addEntity(entity);
        }

        for (ConfigEntity entity : updated) {
            configDao.updateEntity(entity);
        }

        for (ConfigEntity entity : removed) {
            configDao.removeEntity(entity);
        }
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void removeEntity(long... ids)
            throws ConfigException
    {
        for (long id : ids) {
            ConfigEntity entity = configDao.getEntity(id);
            if (entity != null) {
                configDao.removeEntity(entity);
            }
        }
    }

    public ConfigEntity getEntity(long id)
    {
        return configDao.getEntity(id);
    }

    public List<ConfigGroupEntity> listGroup(String ownerType, String ownerId)
    {
        return configDao.listGroup(ownerType, ownerId);
    }

    public ConfigGroupEntity getGroup(long id)
    {
        return configDao.getGroup(id);
    }

    public ConfigGroupEntity getGroup(String ownerType, String ownerId, String key)
    {
        return configDao.getGroup(ownerType, ownerId, key);
    }

    public PagingList<ConfigGroupEntity> queryGroup(String ownerType, String ownerId, Criteria criteria)
    {
        return configDao.queryGroup(ownerType,ownerId,criteria);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void addGroup(ConfigGroupEntity groupEntity)
            throws ConfigException
    {
        configDao.addGroup(groupEntity);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void updateGroup(ConfigGroupEntity groupEntity)
            throws ConfigException
    {
        configDao.updateGroup(groupEntity);
    }

    @TransactionAttribute
    @Transactional (rollbackFor = Exception.class)
    public void removeGroup(long... ids)
            throws ConfigException
    {
        for (long id : ids) {
            ConfigGroupEntity groupEntity = configDao.getGroup(id);
            if (groupEntity != null) {
                configDao.removeGroup(groupEntity);
            }
        }
    }
}
